package utils

import (
	"fmt"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
)

func GetVideoDurationAndCover(videoPath, videoName string) (string, string, error) {
	durationSeconds, err := getVideoDuration(videoPath)
	if err != nil {
		return "", "", err
	}
	formattedDuration := formatDuration(durationSeconds)
	coverBaseName := videoName + "_cover.jpg"
	coverPath := filepath.Join(filepath.Dir("./staticSrc/staticCover/"), coverBaseName)
	if err := extractVideoCover(videoPath, coverPath, durationSeconds/2); err != nil {
		return "", "", err
	}
	return formattedDuration, coverBaseName, nil
}

func formatDuration(seconds float64) string {
	totalSeconds := int(seconds)
	hours := totalSeconds / 3600
	minutes := (totalSeconds % 3600) / 60
	secs := totalSeconds % 60

	return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, secs)
}

func extractVideoCover(videoPath, coverPath string, seekSeconds float64) error {
	// 避免提取点为0
	if seekSeconds <= 0 {
		seekSeconds = 1.0
	}

	cmd := exec.Command("ffmpeg", "-y", "-ss", fmt.Sprintf("%f", seekSeconds),
		"-i", videoPath, "-vframes", "1", "-q:v", "2", coverPath)

	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("ffmpeg error: %v, output: %s", err, string(output))
	}

	return nil
}

func getVideoDuration(videoPath string) (float64, error) {
	cmd := exec.Command("ffprobe", "-v", "error", "-show_entries",
		"format=duration", "-of", "default=noprint_wrappers=1:nokey=1", videoPath)

	output, err := cmd.CombinedOutput()
	if err != nil {
		return 0, fmt.Errorf("ffprobe error: %v, output: %s", err, string(output))
	}

	duration, err := strconv.ParseFloat(strings.TrimSpace(string(output)), 64)
	if err != nil {
		return 0, fmt.Errorf("invalid duration output: %s", string(output))
	}

	return duration, nil
}
